home *** CD-ROM | disk | FTP | other *** search
/ Space & Astronomy / Space and Astronomy (October 1993).iso / mac / programs / satrack / SS4EXE.ZIP / SEESAT4.ZIP / READEL.C < prev    next >
Text File  |  1992-01-05  |  18KB  |  752 lines

  1. /*
  2. READEL.C
  3. by Paul S. Hirose, 1992 Jan 4
  4. Handles orbital element files and reads the elements.
  5.  
  6. This file is in the public domain.
  7.  
  8. 400 - 499
  9.  
  10. library functions, typedefs, and #defines used in this file:
  11.  
  12. atof atoi cos EOF fclose FILE fopen free fseek ftell getc isdigit
  13. isspace NULL printf strcmp strcpy strncpy
  14. */
  15.  
  16. #include "b:seesat.h"    /* global header */
  17.  
  18. #if ECOC
  19. extern void free(), printf();
  20. extern char *strcpy(), *strncpy();
  21. extern long int fseek(), ftell();
  22. extern double atof(), cos();
  23. extern FILE *fopen();
  24. #endif
  25.  
  26. /* Number of lines on your terminal.  Only affects the listing of satellite
  27. names.  You will get LINES-1 rows of names, followed by "more>" on a separate
  28. line.  The cursor will be positioned to the right of '>'. */
  29. #define LINES 24
  30.  
  31. /* Number of chars to allow for satellite name in index. */
  32. #define LNAME 22
  33.  
  34. #define BSIZE 50    /* # of index entries in a storage block */
  35.  
  36. #define NSTAT 0        /* normally 0.  Non-zero makes static functions
  37.             and data extern, for testing */
  38.  
  39. #define MAGCOL 31    /* position (far left = 0) of magnitude column */
  40.  
  41.  
  42. #if NSTAT
  43. /* define & declare all functions in this file as extern */
  44. #define STATIC
  45. #define SC extern
  46.  
  47. #else
  48. #define STATIC static
  49. #define SC static
  50. #endif
  51.  
  52. /*############################ LOCAL DATA ############################*/
  53.  
  54. /* RAAN and epoch.  Not modified by NOMINAL and ACTUAL commands. */
  55. STATIC double node, epocho;
  56.  
  57. /* nominal & actual launch times */
  58. STATIC double tnom, tact;
  59.  
  60. STATIC FILE *fp = NULL;        /* orbital element file */
  61.  
  62. /* Index entry.  Each satellite has one. */
  63. struct indent {
  64.     char name[LNAME+1];    /* satellite name */
  65.     long int offset;    /* location of element set in file */
  66. };
  67.  
  68. struct bloc {    /* space for BSIZE index entries */
  69.     struct indent ents[BSIZE];
  70.     struct bloc *next;    /* link to next block */
  71. };
  72.  
  73. STATIC struct bloc *first;    /* ptr to first block */
  74.  
  75. STATIC unsigned sets;        /* number of element sets in file */
  76. STATIC unsigned maxnc = LNAME;    /* max no. of name chars to read */
  77.  
  78. /*######################## LOCAL FUNCTIONS ########################*/
  79.  
  80. SC void adjel();    /* adjust RAAN & epoch for launch time */
  81. SC double angle();    /* convert string to angle in radians */
  82. SC int csum();        /* checksums a line of data */
  83. SC double elmod();    /* convert cmd line arg to double */
  84. SC double epjd();    /* converts NORAD Epoch string to epoch */
  85. SC int getel();        /* transfers elements from file to variables */
  86. SC void nullsp();    /* replace spaces in buffer with nulls */
  87. SC double sci();    /* returns value of scientific notation #'s */
  88. SC char *sknull();    /* skip leading nulls */
  89.  
  90. /*############################## CODE ##############################*/
  91.  
  92.  
  93. STATIC void
  94. adjel()
  95. /* adjust RAAN & epoch for difference between actual & nominal launch time */
  96. {
  97.     double deltat;
  98.  
  99.     deltat = tact - tnom;
  100.  
  101.     epoch = epocho + deltat;
  102.     xnodeo = fmod2p(node + 4.37527e-3 * deltat);
  103.     iflag = 1;
  104. }
  105.  
  106.  
  107. STATIC double
  108. angle(string)
  109. char *string;
  110. /* Returns the radian value of the angle (degrees) in "string".
  111. Leading nulls on "string" will be skipped, so it had better contain
  112. at least one digit. */
  113. {
  114.     return atof(sknull(string)) * de2ra;
  115. }
  116.  
  117.  
  118. void
  119. aop()        /* alter argument of the perigee */
  120. {
  121.     omegao = elmod() * de2ra;
  122. }
  123.  
  124.  
  125. void
  126. b()        /* alter bstar */
  127. {
  128.     bstar = elmod();
  129. }
  130.  
  131.  
  132. STATIC int
  133. csum(line)
  134. char *line;
  135. /* Does a checksum modulo 10 on the given line.  Digits = their
  136. value, '-' = 1, all other chars = 0.  Returns 0 if ok. */
  137. {
  138.     char c;
  139.     int i = 0;    /* checksum accumulator */
  140.     int count = 69;        /* length of data line */
  141.  
  142.     /* accumulate checksum from all but the last char in the line,
  143.     which is the desired checksum */
  144.  
  145.     while (--count) {
  146.         if (isdigit(c = *line++))
  147.             i += c - '0';
  148.         else if (c == '-')
  149.             ++i;
  150.         /* all other chars = 0 */
  151.     }
  152.  
  153.     /* Convert accumulated # to mod 10, subtract desired sum */
  154.     return i % 10 - (*line - '0');
  155. }
  156.  
  157.  
  158. void
  159. ein()        /* alter eccentricity */
  160. {
  161.     eo = elmod();
  162. }
  163.  
  164.  
  165. STATIC double
  166. elmod()
  167. /* tasks common to nearly all commands that modify orbital elements */
  168. {
  169.     iflag = 1;    /* since elements will be altered */
  170.     return atof(*tokp);
  171. }
  172.  
  173.  
  174. STATIC double
  175. epjd(buf)
  176. char *buf;
  177. /* Given pointer to the orbital elements Epoch field, returns Julian Date
  178. (unit = minutes).  Positions for Days tens and hundreds and Years tens digits
  179. must contain either a digit or '\0'.  Format of Epoch field:  YYDDD.dddddddd
  180. */
  181. {    
  182.     double day;
  183.     int year;
  184.  
  185.     day = atof(sknull(buf + 2));
  186.  
  187.     buf[2] = '\0';            /* day 100s digit = null */
  188.     year = atoi(sknull(buf));
  189.     year += (year < 57) ? 1999 : 1899;
  190.  
  191.     /* Subtract .5 because julday() returns JD at 12h on given day */
  192.     return (julday(year, 11, 31) + day - .5) * xmnpda;
  193. }
  194.  
  195.  
  196. void
  197. epoc()
  198. /* sets epoch of elements from command line */
  199. {
  200.     nullsp(*tokp);        /* turn any spaces to nulls */
  201.     epoch = epocho = epjd(*tokp);
  202. #if ENPRE    /* precession code enabled */
  203.     /* initialize direction cosines to precess R.A./dec. */
  204.     inpre();
  205. #endif
  206. }
  207.  
  208.  
  209. STATIC int
  210. getel()
  211. /* Sets the global orbital element variables and name[] (satellite name)
  212. using data from the currently open element file.  Initializes precession. 
  213. Sets global iflag to 1.  The position in the file must be at the satellite
  214. name or in white space preceding the name.  Returns -1 if incorrect format in
  215. file, 0 otherwise.  Prints warning if checksum error in file, but will still
  216. attempt to use elements. */
  217. {
  218. #if 0
  219.     double ao, a1, delo, del1;    /* currently not used */
  220. #endif
  221.     double temp;
  222.     int check;
  223.     char line1[70], line2[70];
  224.  
  225.     /* extract name of satellite */
  226.     if ((check = getlin(line1, 70, fp)) == 0)    /* EOF */
  227.         return -1;
  228.     printf("%s\n", line1);
  229.     strncpy(name, line1, maxnc);
  230.     name[maxnc] = '\0';
  231.  
  232.     /* If line is long enough, extract magnitude and set mag flag. */
  233.  
  234.     if (check > MAGCOL) {
  235.         nullsp(line1);
  236.         abmag = atof(sknull(line1 + MAGCOL));
  237.         mflag = '\001';
  238.     } else {
  239.         abmag = 0.;
  240.         mflag = '\000';
  241.     }
  242.  
  243.     /* Get first data line from file.  Verify that it's 69 chars long &
  244.     begins with '1' */
  245.  
  246.     if (getlin(line1, 70, fp) != 69 || *line1 != '1')
  247.         return -1;    /* incorrect format */
  248.     check = csum(line1);    /* Line 1 checksum */
  249.  
  250.     /* get second data line */
  251.     if (getlin(line2, 70, fp) != 69 || *line2 != '2')
  252.         return -1;    /* incorrect format */
  253.     check += csum(line2);    /* add Line 2 checksum */
  254.  
  255.     /* print both lines at console */
  256.     printf("%s\n%s\n", line1, line2);
  257.     if (check)
  258.         printf("CAUTION:  FAILED CHECKSUM\n");
  259.  
  260.     /* replace spaces with nulls */
  261.     nullsp(line1);
  262.     nullsp(line2);
  263.  
  264.     xmo = angle(line2 + 43);
  265.     xnodeo = node = angle(line2 + 17);
  266.     omegao = angle(line2 + 34);
  267.     xincl = angle(line2 + 8);
  268.     FTEST((400, 4, 3, &xmo, &xnodeo, &omegao, &xincl));
  269.  
  270.     /* put a decimal point in front of eccentricity, decode it */
  271.     line2[25] = '.';
  272.     eo = atof(line2 + 25);
  273.  
  274.     temp = twopi / (xmnpda * xmnpda);
  275.  
  276.     /* Make sure mean motion is null-terminated, since rev. no.
  277.     may immediately follow. */
  278.     line2[63] = '\0';
  279.     xno = atof(sknull(line2 + 52)) * temp * xmnpda;
  280.  
  281.     if (line1[35])        /* field isn't blank */
  282.         xndt2o = atof(sknull(line1 + 33)) * temp;
  283.     else
  284.         xndt2o = 0.;
  285.     xndd6o = sci(line1 + 44) * temp / xmnpda;
  286.  
  287.     bstar = sci(line1 + 53);
  288.     epoch = epocho = epjd(line1 + 18);
  289.     ETEST((402, 5, 3, &eo, &xno, &xndt2o, &xndd6o, &bstar));
  290.     FTEST((403, 1, 3, &epoch));
  291.  
  292.     toffs = 0.;    /* reset OFFSET */
  293.     iflag = 1;
  294.  
  295. #if ENPRE    /* precession code enabled */
  296.     /* initialize direction cosines to precess R.A./dec. */
  297.     inpre();
  298. #endif
  299.  
  300. #if 0
  301.     /* Spacetrack Report #3 code for distinguishing between near earth or
  302.     deep space satellites.  Provided for completeness but not used. */
  303.  
  304.     /* Compute period.  Object is deep space if <= 6.4 revs/day */
  305.     a1 = POW(xke / xno, tothrd);
  306.     temp = cos(xincl);
  307.     temp = 1.5 * ck2 * (3. * temp * temp - 1.) /
  308.       POW(1. - eo * eo, 1.5);
  309.     del1 = temp / (a1 * a1);
  310.     ao = a1 * (1. - del1 * (.5 * tothrd + del1 *
  311.       (1. + 134. / 81. * del1)));
  312.     delo = temp / (ao * ao);
  313.  
  314.     if (xno / (1. + delo) <= .0279253)
  315.         return 1;    /* deep space */
  316.     else
  317. #endif
  318.         return 0;    /* near earth */
  319. }
  320.  
  321.  
  322. #if LASERC == 0
  323.  
  324. int
  325. getlin(dest, size, filep)
  326. int size;    /* must be at least 2 */
  327. char *dest;
  328. FILE *filep;
  329. /* Copy a line from filep into dest[].  "Size" is length of dest[], and must
  330. be at least 2.  Any leading white space is skipped.  String copied to dest[]
  331. will be null terminated.
  332.      Exit occurs when:  1) size - 1 chars have been copied, or 2) '\n'
  333. detected (the '\n' won't be sent to dest[]), or 3) EOF detected.  In case 1
  334. or 2, the next read from the file is guaranteed to start at beginning of the
  335. next line.  Returns # of chars copied to dest[] (final null not counted). */
  336. {
  337.     int c, i;
  338.  
  339.     i = size - 1;    /* i = # of chars desired */
  340.  
  341.     /* go past leading white space */
  342.     while (isspace(c = getc(filep)))
  343.         ;
  344.     DTEST((450, 2, &i, &c));
  345.  
  346.     /* Move chars to buffer till we we reach end of line, or
  347.     have gotten # requested, or end of file. */
  348.  
  349.     do {
  350.         if (c == EOF)
  351.             break;
  352.         *dest++ = c;
  353.     } while (--i && (c = getc(filep)) != '\n');
  354.     *dest = '\0';
  355.     DTEST((451, 2, &i, &c));
  356.     STEST((452, dest));
  357.  
  358.     /* At this point, i is how many chars we've fallen short */
  359.  
  360.     if (!i)        /* requested # of chars were found */
  361.         while ((c = getc(filep)) != '\n' && c != EOF)
  362.             ;    /* position at start of next line */
  363.  
  364.     DTEST((453, 2, &i, &c));
  365.     return size - 1 - i;    /* how many copied */
  366. }
  367.  
  368. #endif
  369.  
  370.  
  371. #if LASERC
  372. /* A bug in Laser C's ftell() forces us to open element file in binary mode,
  373. which in turn necessitates this special version of getlin(). */
  374.  
  375. int
  376. getlin(dest, size, filep)
  377. int size;    /* must be at least 2 */
  378. char *dest;
  379. FILE *filep;
  380. /* Copy a line from filep into dest[].  "Size" is length of dest[], and must
  381. be at least 2.  Any leading white space is skipped.  String copied to dest[]
  382. will be null terminated.
  383.      Exit occurs when:  1) size - 1 chars have been copied, or 2) '\n'
  384. detected (the '\n' won't be sent to dest[]), or 3) EOF detected.  In case 1
  385. or 2, the next read from the file is guaranteed to start at beginning of the
  386. next line.  Returns # of chars copied to dest[] (final null not counted). */
  387. {
  388.     int c, i;
  389.  
  390.     i = size - 1;    /* i = # of chars desired */
  391.  
  392.     /* go past leading white space */
  393.     while (isspace(c = getc(filep)))
  394.         ;
  395.  
  396.     /* Move chars to buffer till we we reach end of line, or
  397.     have gotten # requested, or end of file. */
  398.  
  399.     do {
  400.         if (c == EOF  ||  c == 0x1A)
  401.             break;        /* physical or logical end of file */
  402.         *dest++ = c;
  403.     } while (--i && (c = getc(filep)) != '\n');
  404.  
  405.     /* if last char written was a CR, kill it */
  406.     if (*(dest - 1) == 0xD) {
  407.         --dest;
  408.         ++i;
  409.     }
  410.  
  411.     *dest = '\0';
  412.  
  413.     /* At this point, i is how many chars we've fallen short */
  414.  
  415.     if (!i)        /* requested # of chars were found */
  416.         while ((c = getc(filep)) != '\n' && c != EOF)
  417.             ;    /* position at start of next line */
  418.  
  419.     return size - 1 - i;    /* how many copied */
  420. }
  421.  
  422. #endif
  423.  
  424.  
  425. void
  426. hfree()
  427. /* Follows the chain of index blocks, frees each one */
  428. {
  429.     struct bloc *blocp, *temp;
  430.  
  431.     for (blocp = first; blocp; blocp = temp) {
  432.         temp = blocp->next;
  433.         free((VOIDP) blocp);
  434.     }
  435.     first = NULL;
  436. }
  437.  
  438.  
  439. void
  440. inc()        /* alter inclination */
  441. {
  442.     xincl = elmod() * de2ra;
  443. }
  444.  
  445.  
  446. void
  447. indx()
  448. /* List all satellites in the index generated by opn(). */
  449. {
  450.     unsigned total, u, line, column;
  451.     struct bloc *blocp;
  452.     struct indent *indexp;
  453.  
  454.     total = sets;    /* total no. of element sets in file */
  455.     line = LINES - 1;
  456.     column = 3;
  457.  
  458.     for (blocp = first;  blocp;  blocp = blocp->next) {
  459.         indexp = blocp->ents;        /* 1st index entry in block */
  460.         for (u = BSIZE;    u--; ) {
  461.             if (line == 0) {    /* screen is full */
  462.                 printf("more");
  463.                 tok();        /* cmd line prompt */
  464.                 if (*tokp) {    /* cmd was typed */
  465.                     --tokp;
  466.                     return;
  467.                 } else        /* only a CR was typed */
  468.                     line = LINES - 1;
  469.             }
  470.             if (--column)
  471.                 printf("%-25s", indexp->name);
  472.             else {        /* rightmost column */
  473.                 printf("%s\n", indexp->name);
  474.                 column = 3;
  475.                 --line;
  476.             }
  477.             ++indexp;
  478.             if (--total == 0)
  479.                 break;
  480.     }    }
  481.     if (column != 3)
  482.         printf("\n");
  483.  
  484.     --tokp;        /* because this cmd takes no args */
  485. }
  486.  
  487.  
  488. void
  489. load()
  490. /* Takes the next argument on the command line as the name of the satellite
  491. to load from the currently open file. */
  492. {
  493.     struct bloc *blocp;    /* block pointer */
  494.     struct indent *indexp;    /* index pointer */
  495.     unsigned u, total;
  496.     char *cp;
  497.  
  498.     cp = *tokp;        /* name of satellite */
  499.  
  500.     /* Sequential search for a matching name.  Outer loop checks all
  501.     blocks, inner loop checks all entries in a block. */
  502.     total = sets;        /* no. of sats in index */
  503.     for (blocp = first; blocp != NULL; blocp = blocp->next) {
  504.         indexp = blocp->ents;
  505.         for (u = BSIZE; u && total; --u, --total) {
  506.             if (strcmp(indexp->name, cp) == 0)
  507.                 goto done;    /* found matching name */
  508.             ++indexp;
  509.     }    }
  510.     done:
  511.     if (total) {
  512.     /* found matching name; go to its file position */
  513.         fseek(fp, indexp->offset, 0);
  514.  
  515.         /* get elements, report status */
  516.         if (getel() == 0)
  517.             return;
  518.         else
  519.             printf("ABORTED LOAD:  INCORRECT FORMAT\n");
  520.     } else
  521.         printf("NO SUCH SATELLITE\n");
  522.     LONGJMP(reset, 1);
  523. }
  524.  
  525.  
  526. void
  527. ma()        /* alter mean anomaly */
  528. {
  529.     xmo = elmod() * de2ra;
  530. }
  531.  
  532.  
  533. void
  534. mm()        /* alter mean motion */
  535. {
  536.     xno = elmod() * twopi / xmnpda;        /* radians/min */
  537. }
  538.  
  539.  
  540. void
  541. next()
  542. /* load next sat in file */
  543. {
  544.     if (getel() == -1) {
  545.         printf("END OF ELEMENTS\n");
  546.         LONGJMP(reset, 1);
  547.     }
  548.     --tokp;        /* because this cmd takes no args */
  549. }
  550.  
  551.  
  552. STATIC void
  553. nullsp(buf)
  554. char *buf;
  555. /* replaces each occurrence of ' ' in string "buf" with a null */
  556. {
  557.     char c;
  558.  
  559.     while (c = *buf) {
  560.         if (c == ' ')
  561.             *buf = '\0';
  562.         ++buf;
  563. }    }
  564.  
  565.  
  566. void
  567. opn()
  568. /* Take the next argument on the command line as the name of the orbital
  569. element file to open.  Builds the index used by index() and load().  If an
  570. elements file is already open, it will be closed and the associated index
  571. deleted before opening the new file.  External "fp" is set to the returned
  572. value from fopen(). */
  573. {
  574.     struct bloc *blocp, *last;
  575.     struct indent *indexp;
  576.     FILE *tfp;
  577.     long int fpos;        /* position in file */
  578.     unsigned int n50;
  579.     char *cp, buffer[LNAME + 1];
  580.  
  581.     cp = *tokp;        /* satellite name */
  582. #if LASERC
  583.     if ((tfp = fopen(cp, "br")) == NULL) {
  584. #else
  585.     if ((tfp = fopen(cp, "r")) == NULL) {
  586. #endif
  587.         printf("CAN'T OPEN %s\n", cp);
  588.         LONGJMP(reset, 1);
  589.     }
  590.  
  591.     if (fp) {    /* close old file, delete its index */
  592.         fclose(fp);
  593.         hfree();        /* release index space */
  594.     }
  595.  
  596.     fp = tfp;
  597.     sets = 0;    /* counts # of element sets processed */
  598.     n50 = 0;    /* storage remaining */
  599.     fpos = 0L;    /* position in file */
  600.  
  601.     while (getlin(buffer, maxnc + 1, fp) != 0) {
  602.     /* got a satellite name; add it to index */
  603.         if (n50 == 0) {    /* need more storage */
  604.             blocp = (struct bloc *) MALLOC(sizeof (struct bloc));
  605.             if (blocp == NULL) {
  606.                 printf("MEMORY FULL:  %u INDEXED\n", sets);
  607.                 return;
  608.             }
  609.             if (first == NULL)    /* first block */
  610.                 first = blocp;
  611.             else
  612.                 last->next = blocp;    /* link in */
  613.             last = blocp;        /* new last block */
  614.             blocp->next = NULL;    /* end of chain */
  615.             indexp = blocp->ents;
  616.             n50 = BSIZE;    /* reset storage counter */
  617.         }
  618.         /* storage is available; add the element set to the index */
  619.  
  620.         /* eliminate any trailing spaces on name */
  621.         for (cp = buffer; *++cp; )
  622.             ;    /* find end of name string */
  623.         while (isspace(*--cp))
  624.             ;    /* point to last non-white char */
  625.         cp[1] = '\0';
  626.  
  627.         strcpy(indexp->name, stoup(buffer));
  628.         indexp->offset = fpos;        /* location in file */
  629.  
  630.         getlin(buffer, LNAME + 1, fp);    /* move past Line 1 */
  631.         getlin(buffer, LNAME + 1, fp);    /* move past Line 2 */
  632.         ++sets;            /* # of satellites found */
  633.         --n50;        /* space remaining in index */
  634.         ++indexp;    /* point to next free place in index */
  635.         fpos = ftell(fp);    /* update file position */
  636.     }
  637.     fseek(fp, 0L, 0);    /* rewind */
  638.     printf("complete; %u satellites found\n", sets);
  639. }
  640.  
  641.  
  642. void
  643. raan()        /* alter Right Ascension of Ascending Node */
  644. {
  645.     xnodeo = node = elmod() * de2ra;
  646. }
  647.  
  648.  
  649. STATIC double
  650. sci(string)
  651. char *string;
  652. /* Converts quasi scientific notation to double.  Format:  SnSn where S is
  653. either '-' or '\0' and n represents a sequence of 1 or more digits.  An
  654. implied decimal point exists to the left of the left n.  Total length 27
  655. chars max. */
  656. {
  657.     char buf[30], *bufptr;
  658.  
  659.     bufptr = buf;
  660.  
  661.     if (string[1] == '\0')
  662.         return 0.;
  663.  
  664.     /* get significand */
  665.     if (*string == '-')
  666.         *bufptr++ = '-';
  667.     *bufptr = '.';
  668.     while (isdigit(*++bufptr = *++string))
  669.         ;    /* copy significand */
  670.     *bufptr++ = 'E';
  671.  
  672.     /* get exponent */
  673.     if (*string == '\0')    /* no sign on exponent */
  674.         ++string;
  675.  
  676.     strcpy(bufptr, string);        /* copy exponent */
  677.     return atof(buf);
  678. }
  679.  
  680.  
  681. void
  682. setact()
  683. /* Set actual time of launch, adjust elements accordingly */
  684. {
  685.     tact = tokmin();
  686.     adjel();
  687. }
  688.  
  689.  
  690. void
  691. setlen()
  692. /* Set the max number of chars to be read from the name line in file.
  693. LNAME is size of the space  allocated for the name, in the index. */
  694. {
  695.     int i;
  696.  
  697.     i = atoi(*tokp);
  698.     if (i > LNAME)
  699.         maxnc = LNAME;
  700.     else
  701.         maxnc = i;
  702. }
  703.  
  704.  
  705. void
  706. setnam()
  707. /* manually set name of satellite */
  708. {
  709.     strncpy(name, *tokp, 22);
  710.     name[22] = '\0';
  711. }
  712.  
  713.  
  714. void
  715. setnd()
  716. /* manually input first derivative of mean motion */
  717. {
  718.     xndt2o = elmod() * twopi / (xmnpda * xmnpda);
  719. }
  720.  
  721.  
  722. void
  723. setndd()
  724. /* manually input second derivative of mean motion */
  725. {
  726.     xndd6o = elmod() * twopi / (xmnpda * xmnpda * xmnpda);
  727. }
  728.  
  729.  
  730. void
  731. setnom()
  732. /* set nominal time of launch, adjust the elements accordingly */
  733. {
  734.     tnom = tokmin();
  735.     adjel();
  736. }
  737.  
  738.  
  739. STATIC char *
  740. sknull(cptr)
  741. char *cptr;
  742. /* Skip nulls.  Returns pointer to first non-null char in "cptr". */
  743. {
  744.     while (!*cptr)
  745.         ++cptr;
  746.  
  747.     return cptr;
  748. }
  749. ct()
  750. /* Set actual time of launch, adjust elements accordingly */
  751. {
  752.     tact = tokmin